/*
* $Id: DataValidator.java 70 2012-12-11 12:04:18Z Denis.Skalsky@gmail.com $
*/
package com.globallogic.skalskyy.javabasic.inputdata;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/** 
* DataValidator verifies inputted data.
* @author $Author: Denis.Skalsky@gmail.com $
* @version $Revision: 47 $
*/
public class DataValidator {
	
	private static final String INCOMING_DATE_FORMAT = "dd MMMMM yyyy";
	private static final String BLANK_CHAR = " ";
	private static final String EMPTY_CHAR = "";
	/** Start of integer ASCII code range */
	private static final int START_INT_RANGE = 48;
	/** End of integer ASCII code range */
	private static final int END_INT_RANGE = 57;
	/** Start of uppercase alpha ASCII code range */
	private static final int START_ALPHA_RANGE = 65;
	/** End of uppercase alpha ASCII code range */
	private static final int END_ALPHA_RANGE = 90;

	/** Interface to get inputted data */
	private IncomingData incomingData;
	
	/**
	 * Verify symbols to fit validation rules
	 * @param startRange start of range
	 * @param endRange end of range
	 * @param addSymbols additional symbols
	 * @return result of verification
	 */
	private boolean verifySymbols(String inputtedValue, int startRange, int endRange) {
		boolean result = true;
		
		for (int i = 0; i < inputtedValue.length(); i++) {
			if (((int) inputtedValue.charAt(i) < startRange) ||
				((int) inputtedValue.charAt(i) > endRange)) {
				result = false;
				break;
			}
		};
		
		return result;
	}
	
	/**
	* Set interface to get inputted data
	* @param incomingData Interface to get inputted data
	*/
	public void setIncomingData(IncomingData incomingData) {
		this.incomingData = incomingData;
	}
	
	/**
	 * Get inputted string
	 * @return String value
	 */
	public String getStringValue() {
		String result = this.incomingData.getValue();
		
		if (result.equals(EMPTY_CHAR)) {
			throw new RuntimeException(Messages.EMPTY_STRING);
		};
		
		if (result.replace(BLANK_CHAR, EMPTY_CHAR).equals(EMPTY_CHAR)) {
			throw new RuntimeException(Messages.EMPTY_STRING);
		};
		
		return result;
	}
	
	/**
	* Convert inputted data to positive integer value
	* @return integer positive value	
	*/
	public int getIntPositiveValue() {
		String inputtedValue = this.incomingData.getValue();
		
		if (!this.verifySymbols(
				inputtedValue, 
				DataValidator.START_INT_RANGE, 
				DataValidator.END_INT_RANGE)) {
			throw new RuntimeException(Messages.NOT_NUMBERS_VALUE);
		};
		
		int result = Integer.parseInt(inputtedValue);

		return result;
	}
	
	/**
	* Convert inputted data to array of string with two words
	* @return String[] with two words
	*/
	public String[] getTwoWords() {
		String inputtedValue = this.incomingData.getValue().toUpperCase();
		
		if (!this.verifySymbols(
				inputtedValue.replace(BLANK_CHAR, EMPTY_CHAR),
				DataValidator.START_ALPHA_RANGE, 
				DataValidator.END_ALPHA_RANGE)) {
			throw new RuntimeException(Messages.NOT_ALPHA_SYMBOLS);
		};
		
		String[] result = inputtedValue.split(BLANK_CHAR); 
		
	    if (result.length == 1) {
	    	throw new RuntimeException(Messages.ONLY_ONE_WORD_ENTERED);
	    };		
	    	    
		return result;
	}	
	
	/**
	 * Convert inputted data to array of positive integer
	 * @return int[] with positive integer
	 */
	public int[] getListOfPositiveIntValue() {
		String inputtedData = this.incomingData.getValue().toUpperCase();
		
		if (!this.verifySymbols(
				inputtedData.replace(BLANK_CHAR, EMPTY_CHAR),
				DataValidator.START_INT_RANGE, 
				DataValidator.END_INT_RANGE)) {
			throw new RuntimeException(Messages.NOT_NUMBERS_VALUE);
		};
		
		String[] inputtedStrings = inputtedData.split(BLANK_CHAR);
		if (inputtedStrings.length == 1) {
			throw new RuntimeException(Messages.ONLY_ONE_NUMBER_ENTERED);
		};
		
		int[] result = new int[inputtedStrings.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = Integer.parseInt(inputtedStrings[i]);
		};
		
		return result;
	};
	
	/**
	 * Convert inputted data to date
	 * @return date
	 */
	public Date getDateValue() {
		Date result = new Date();
		try {
			result = (new SimpleDateFormat(INCOMING_DATE_FORMAT)).parse(this.incomingData.getValue());
		} catch (ParseException e) {
			throw new RuntimeException(Messages.INVALID_DATE_FORMAT);
		};
		
		return result;
	}
}